﻿#include "SceneGlobal.h"

#include "Render/VulkanContext.h"
#include "Render/PreRender/PreRenderShader.h"
#include "Render/Material/VulkanShaders.h"
#include "Render/Material/VulkanShader.h"
#include "Primitive/Vertex.h"

void CSceneGlobal::Init()
{
    CreateModelDescriptorSetLayout();
    CreateSceneParameterLayout();
    CreateShadowMapSampler();
    DefferRenderingOutputSampler=ShadowMapSampler;

    CreatePointLightShadowMapThings();
    CreateSpotLightShadowMapThings();
    CreateDirectionalLightShadowMapThings();

    CreateSceneRenderPass();
    CreateDefferShadingPipelines();

    CreateAntiAliasingPipeline();
}

void CSceneGlobal::CreateModelDescriptorSetLayout()
{
    vk::DescriptorSetLayoutBinding DescriptorSetLayoutBinding[1];
    DescriptorSetLayoutBinding[0]=vk::DescriptorSetLayoutBinding()
        .setBinding(0)
        .setDescriptorType(vk::DescriptorType::eUniformBuffer)
        .setDescriptorCount(1)
        .setStageFlags(vk::ShaderStageFlagBits::eVertex)
        .setPImmutableSamplers(nullptr);

    vk::DescriptorSetLayoutCreateInfo DescriptorSetLayoutCreateInfo=vk::DescriptorSetLayoutCreateInfo()
        .setBindingCount(1)
        .setPBindings(DescriptorSetLayoutBinding);

    BatchModelDescriptorSetLayout.Layout=CVulkanContext::Get()->GetDevice().createDescriptorSetLayout(DescriptorSetLayoutCreateInfo);
    BatchModelDescriptorSetLayout.DescriptorNums.UniformBufferDescriptorNum=1;

    ModelDescriptorSetLayout=BatchModelDescriptorSetLayout;
}    

void CSceneGlobal::CreateSceneParameterLayout()
{
    //创建场景全局参数描述布局
    vk::DescriptorSetLayoutCreateInfo SceneParameterLayoutInfo;
    SceneParameterLayoutInfo.bindingCount = 1;
    vk::DescriptorSetLayoutBinding SceneParameterBinding;
    SceneParameterBinding.binding = 0;
    SceneParameterBinding.descriptorType = vk::DescriptorType::eUniformBuffer;
    SceneParameterBinding.descriptorCount = 1;
    SceneParameterBinding.stageFlags = 
        vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment;
    SceneParameterLayoutInfo.pBindings = &SceneParameterBinding;
    SceneParameterLayout = 
        CVulkanContext::Get()->GetDevice().createDescriptorSetLayout(SceneParameterLayoutInfo);
}

void CSceneGlobal::CreateShadowMapSampler()
{
    vk::Filter ShadowMapFilter=vk::Filter::eLinear;

    vk::SamplerCreateInfo SamplerInfo=vk::SamplerCreateInfo()
    .setMagFilter(ShadowMapFilter)
    .setMinFilter(ShadowMapFilter)
    .setMipmapMode(vk::SamplerMipmapMode::eNearest)
    .setAddressModeU(vk::SamplerAddressMode::eClampToEdge)
    .setAddressModeV(vk::SamplerAddressMode::eClampToEdge)
    .setAddressModeW(vk::SamplerAddressMode::eClampToEdge)
    .setMaxAnisotropy(1.f)
    .setMaxLod(1.f)
    .setBorderColor(vk::BorderColor::eFloatOpaqueWhite)
    ;

    ShadowMapSampler=CVulkanContext::Get()->GetDevice().createSampler(SamplerInfo);
}

void CSceneGlobal::CreateSceneRenderPass()
{

    //多个个子通道
    //first subpass: render mesh to gbuffer
    //second subpass: composite gbuffer to final image
    //第三个子通道:  渲染自发光物体
    //第四个子通道:  渲染透明


    //第一个子通道输出4个颜色附件 并使用1个深度附件
    //,normalAndRoughness(RGBA-16)
    //,positionAndMetal(RGBA-16)
    //,Misc(RGBA-16)
    //,depth(D-32)

    //第二个子通道输入4个颜色附件,输出一个颜色附件(output)

    //第三个子通道输入output附件，继续使用深度附件，无光照

    //第三个子通道输入output附件，继续使用深度附件，有光照

    
    vk::AttachmentDescription AlbedoAndAo=vk::AttachmentDescription()
        .setFormat(vk::Format::eR16G16B16A16Sfloat)
        .setSamples(vk::SampleCountFlagBits::e1)
        .setLoadOp(vk::AttachmentLoadOp::eClear)
        .setStoreOp(vk::AttachmentStoreOp::eStore)
        .setStencilLoadOp(vk::AttachmentLoadOp::eDontCare)
        .setStencilStoreOp(vk::AttachmentStoreOp::eDontCare)
        .setInitialLayout(vk::ImageLayout::eUndefined)
        .setFinalLayout(vk::ImageLayout::eColorAttachmentOptimal);

    vk::AttachmentDescription NormalAndRoughness=vk::AttachmentDescription()
        .setFormat(vk::Format::eR16G16B16A16Sfloat)
        .setSamples(vk::SampleCountFlagBits::e1)
        .setLoadOp(vk::AttachmentLoadOp::eClear)
        .setStoreOp(vk::AttachmentStoreOp::eStore)
        .setStencilLoadOp(vk::AttachmentLoadOp::eDontCare)
        .setStencilStoreOp(vk::AttachmentStoreOp::eDontCare)
        .setInitialLayout(vk::ImageLayout::eUndefined)
        .setFinalLayout(vk::ImageLayout::eColorAttachmentOptimal);

    vk::AttachmentDescription PositionAndMetal=vk::AttachmentDescription()
        .setFormat(vk::Format::eR16G16B16A16Sfloat)
        .setSamples(vk::SampleCountFlagBits::e1)
        .setLoadOp(vk::AttachmentLoadOp::eClear)
        .setStoreOp(vk::AttachmentStoreOp::eStore)
        .setStencilLoadOp(vk::AttachmentLoadOp::eDontCare)
        .setStencilStoreOp(vk::AttachmentStoreOp::eDontCare)
        .setInitialLayout(vk::ImageLayout::eUndefined)
        .setFinalLayout(vk::ImageLayout::eColorAttachmentOptimal);

    vk::AttachmentDescription Misc =vk::AttachmentDescription()
        .setFormat(vk::Format::eR16G16B16A16Sfloat)
        .setSamples(vk::SampleCountFlagBits::e1)
        .setLoadOp(vk::AttachmentLoadOp::eClear)
        .setStoreOp(vk::AttachmentStoreOp::eStore)
        .setStencilLoadOp(vk::AttachmentLoadOp::eDontCare)
        .setStencilStoreOp(vk::AttachmentStoreOp::eDontCare)
        .setInitialLayout(vk::ImageLayout::eUndefined)
        .setFinalLayout(vk::ImageLayout::eColorAttachmentOptimal);

    vk::AttachmentDescription Depth=vk::AttachmentDescription()
        .setFormat(vk::Format::eD32Sfloat)
        .setSamples(vk::SampleCountFlagBits::e1)
        .setLoadOp(vk::AttachmentLoadOp::eClear)
        .setStoreOp(vk::AttachmentStoreOp::eStore)
        .setStencilLoadOp(vk::AttachmentLoadOp::eDontCare)
        .setStencilStoreOp(vk::AttachmentStoreOp::eDontCare)
        .setInitialLayout(vk::ImageLayout::eUndefined)
        .setFinalLayout(vk::ImageLayout::eDepthStencilAttachmentOptimal);

    vk::AttachmentDescription Output=  vk::AttachmentDescription()
        .setFormat(vk::Format::eR16G16B16A16Sfloat)
        .setSamples(vk::SampleCountFlagBits::e1)
        .setLoadOp(vk::AttachmentLoadOp::eClear)
        .setStoreOp(vk::AttachmentStoreOp::eStore)
        .setStencilLoadOp(vk::AttachmentLoadOp::eDontCare)
        .setStencilStoreOp(vk::AttachmentStoreOp::eDontCare)
        .setInitialLayout(vk::ImageLayout::eUndefined)
        .setFinalLayout(vk::ImageLayout::eColorAttachmentOptimal);

    vk::AttachmentReference AlbedoAndAoReference=vk::AttachmentReference()
        .setAttachment(0)
        .setLayout(vk::ImageLayout::eColorAttachmentOptimal);

    vk::AttachmentReference NormalAndRoughnessReference=vk::AttachmentReference()
        .setAttachment(1)
        .setLayout(vk::ImageLayout::eColorAttachmentOptimal);

    vk::AttachmentReference PositionAndMetalReference=vk::AttachmentReference()
        .setAttachment(2)
        .setLayout(vk::ImageLayout::eColorAttachmentOptimal);
    
    vk::AttachmentReference MiscReference=vk::AttachmentReference()
        .setAttachment(3)
        .setLayout(vk::ImageLayout::eColorAttachmentOptimal);
    

    vk::AttachmentReference OutputReference=vk::AttachmentReference()
        .setAttachment(4)
        .setLayout(vk::ImageLayout::eColorAttachmentOptimal);
    vk::AttachmentReference DepthReference=vk::AttachmentReference()
        .setAttachment(5)
        .setLayout(vk::ImageLayout::eDepthStencilAttachmentOptimal);

    TVector<vk::AttachmentReference> FirstSubpassColorAttachments=
    {
        AlbedoAndAoReference,
        NormalAndRoughnessReference,
        PositionAndMetalReference,
        MiscReference,
    };

    vk::SubpassDescription FirstSubpassDescription=vk::SubpassDescription()
        .setPipelineBindPoint(vk::PipelineBindPoint::eGraphics)
        .setColorAttachments(FirstSubpassColorAttachments)
        .setPDepthStencilAttachment(&DepthReference);


    TVector<vk::AttachmentReference> SecondSubpassInputAttachments=
    {
        vk::AttachmentReference(0,vk::ImageLayout::eShaderReadOnlyOptimal),
        vk::AttachmentReference(1,vk::ImageLayout::eShaderReadOnlyOptimal),
        vk::AttachmentReference(2,vk::ImageLayout::eShaderReadOnlyOptimal),
        vk::AttachmentReference(3,vk::ImageLayout::eShaderReadOnlyOptimal),        
    };

    //second subpass
    vk::SubpassDescription SecondSubpassDescription=vk::SubpassDescription()
        .setPipelineBindPoint(vk::PipelineBindPoint::eGraphics)
        .setInputAttachments(SecondSubpassInputAttachments)
        .setColorAttachmentCount(1)
        .setPColorAttachments(&OutputReference);

    //第三个子通道
    vk::SubpassDescription ThirdSubpassDescription=vk::SubpassDescription()
        .setPipelineBindPoint(vk::PipelineBindPoint::eGraphics)
        .setColorAttachmentCount(1)
        .setPColorAttachments(&OutputReference)
        .setPDepthStencilAttachment(&DepthReference);

    //第四个子通道
    vk::SubpassDescription FourthSubpassDescription=vk::SubpassDescription()
        .setPipelineBindPoint(vk::PipelineBindPoint::eGraphics)
        .setColorAttachmentCount(1)
        .setPColorAttachments(&OutputReference)
        .setPDepthStencilAttachment(&DepthReference);

    TVector<vk::SubpassDescription> SubpassDescriptions=
    {
        FirstSubpassDescription,
        SecondSubpassDescription,
        ThirdSubpassDescription,
        FourthSubpassDescription
    };


    TVector<vk::SubpassDependency> SubpassDependencies=
    {
        vk::SubpassDependency()
        .setSrcSubpass(VK_SUBPASS_EXTERNAL)
        .setDstSubpass(0)
        .setSrcStageMask(vk::PipelineStageFlagBits::eColorAttachmentOutput)
        .setDstStageMask(vk::PipelineStageFlagBits::eColorAttachmentOutput)
        .setSrcAccessMask(vk::AccessFlagBits::eColorAttachmentWrite)
        .setDstAccessMask(vk::AccessFlagBits::eColorAttachmentWrite),

        vk::SubpassDependency()
        .setSrcSubpass(0)
        .setDstSubpass(1)
        .setSrcStageMask(vk::PipelineStageFlagBits::eColorAttachmentOutput)
        .setDstStageMask(vk::PipelineStageFlagBits::eFragmentShader)
        .setSrcAccessMask(vk::AccessFlagBits::eColorAttachmentWrite)
        .setDstAccessMask(vk::AccessFlagBits::eShaderRead)
        .setDependencyFlags(vk::DependencyFlagBits::eByRegion)
        ,        

        vk::SubpassDependency()
        .setSrcSubpass(1)
        .setDstSubpass(2)
        .setSrcStageMask(vk::PipelineStageFlagBits::eColorAttachmentOutput)
        .setDstStageMask(vk::PipelineStageFlagBits::eFragmentShader)
        .setSrcAccessMask(vk::AccessFlagBits::eColorAttachmentWrite)
        .setDstAccessMask(vk::AccessFlagBits::eShaderWrite)
        .setDependencyFlags(vk::DependencyFlagBits::eByRegion)

        ,

        vk::SubpassDependency()
        .setSrcSubpass(2)
        .setDstSubpass(3)
        .setSrcStageMask(vk::PipelineStageFlagBits::eColorAttachmentOutput)
        .setDstStageMask(vk::PipelineStageFlagBits::eFragmentShader)
        .setSrcAccessMask(vk::AccessFlagBits::eColorAttachmentWrite)
        .setDstAccessMask(vk::AccessFlagBits::eShaderWrite)
        .setDependencyFlags(vk::DependencyFlagBits::eByRegion)

    };

    TVector<vk::AttachmentDescription> AttachmentDescriptions=
    {
        AlbedoAndAo,
        NormalAndRoughness,
        PositionAndMetal,
        Misc,
        Output,
        Depth,
    };
    //renderpass
    vk::RenderPassCreateInfo RenderPassCreateInfo=vk::RenderPassCreateInfo()
        .setAttachments(AttachmentDescriptions)
        .setSubpasses(SubpassDescriptions)
        .setDependencies(SubpassDependencies)
        ;

    SceneRenderPass=CVulkanContext::Get()->GetDevice().createRenderPass(RenderPassCreateInfo);    

}

void CSceneGlobal::CreateDefferShadingPipelines()
{
    //创建延迟着色的描述符布局
    //create gbuffer descriptor set layout in sencond subpass
    TVector<vk::DescriptorSetLayoutBinding> SecondPassInputLayoutBindings=
    {
        //use first pass 3 color attachments and shadowmap  as input attachment
        
        //albedo and ao
        vk::DescriptorSetLayoutBinding()
            .setBinding(0)
            .setDescriptorType(vk::DescriptorType::eInputAttachment)
            .setDescriptorCount(1)
            .setStageFlags(vk::ShaderStageFlagBits::eFragment)
            .setPImmutableSamplers(nullptr)
        ,

        //normal and roughness
        vk::DescriptorSetLayoutBinding()
            .setBinding(1)
            .setDescriptorType(vk::DescriptorType::eInputAttachment)
            .setDescriptorCount(1)
            .setStageFlags(vk::ShaderStageFlagBits::eFragment)
            .setPImmutableSamplers(nullptr)
        ,

        //position and metal
        vk::DescriptorSetLayoutBinding()
            .setBinding(2)
            .setDescriptorType(vk::DescriptorType::eInputAttachment)
            .setDescriptorCount(1)
            .setStageFlags(vk::ShaderStageFlagBits::eFragment)
            .setPImmutableSamplers(nullptr)
        ,

        //misc
        vk::DescriptorSetLayoutBinding()
            .setBinding(3)
            .setDescriptorType(vk::DescriptorType::eInputAttachment)
            .setDescriptorCount(1)
            .setStageFlags(vk::ShaderStageFlagBits::eFragment)
            .setPImmutableSamplers(nullptr)
    };

    {
        vk::DescriptorSetLayoutCreateInfo DescriptorSetLayoutCreateInfo = vk::DescriptorSetLayoutCreateInfo()
            .setBindings(SecondPassInputLayoutBindings);

        DefferShadingDescriptorSetLayout.Layout =CVulkanContext::Get()->GetDevice().createDescriptorSetLayout(DescriptorSetLayoutCreateInfo);
        DefferShadingDescriptorSetLayout.DescriptorNums.InputAttachmentDescriptorNum=4;
    }


    //创建延迟着色的管线


    //create Spot light descriptor set layout in sencond subpass
    {
        TVector<vk::DescriptorSetLayoutBinding> DescriptorSetLayoutBindings=
        {
            //shadow map
            vk::DescriptorSetLayoutBinding()
                .setBinding(0)
                .setDescriptorType(vk::DescriptorType::eCombinedImageSampler)
                .setDescriptorCount(1)
                .setStageFlags(vk::ShaderStageFlagBits::eFragment)
                .setPImmutableSamplers(nullptr)
        };


        vk::DescriptorSetLayoutCreateInfo DescriptorSetLayoutCreateInfo = vk::DescriptorSetLayoutCreateInfo()
            .setBindings(DescriptorSetLayoutBindings);

        SpotLightDefferShadingDescriptorSetLayout.Layout =CVulkanContext::Get()->GetDevice().createDescriptorSetLayout(DescriptorSetLayoutCreateInfo);
        SpotLightDefferShadingDescriptorSetLayout.DescriptorNums.CombinedImageSamplerDescriptorNum=1;


        //create pipeline layout, use a push constant for the camera position and light info
        TVector<vk::PushConstantRange> PushConstantRanges=
        {
            vk::PushConstantRange()
            .setStageFlags(vk::ShaderStageFlagBits::eFragment)
            .setOffset(0)
            .setSize(sizeof(SSpotLightDefferShadingFragmentPushConstant))
            ,
        };

        TVector<vk::DescriptorSetLayout> DescriptorSetLayouts=
        {
            DefferShadingDescriptorSetLayout.Layout,
            SpotLightDefferShadingDescriptorSetLayout.Layout
        };

        vk::PipelineLayoutCreateInfo PipelineLayoutCreateInfo = vk::PipelineLayoutCreateInfo()
            .setSetLayouts(DescriptorSetLayouts)
            .setPushConstantRanges(PushConstantRanges);

        SpotLightDefferShadingPipelineLayout =CVulkanContext::Get()->GetDevice().createPipelineLayout(PipelineLayoutCreateInfo);

        //create pipeline
        auto VertexShader=CVulkanContext::Get()->GetShaderManager()->GetVulkanOnlyShader(U"DefferShadingVertex");
        auto FragmentShader= CVulkanContext::Get()->GetShaderManager()->GetVulkanOnlyShader(U"SpotLightDefferShadingFragment");

        //dynamic state
        vk::DynamicState DynamicState[2]={vk::DynamicState::eViewport,vk::DynamicState::eScissor};

        vk::PipelineDynamicStateCreateInfo PipelineDynamicStateCreateInfo=vk::PipelineDynamicStateCreateInfo()
            .setDynamicStateCount(2)
            .setPDynamicStates(DynamicState);

        vk::PipelineShaderStageCreateInfo PipelineShaderStageCreateInfo[2];
        PipelineShaderStageCreateInfo[0]=vk::PipelineShaderStageCreateInfo()
            .setStage(vk::ShaderStageFlagBits::eVertex)
            .setModule(VertexShader->Module)
            .setPName("main");

        PipelineShaderStageCreateInfo[1]=vk::PipelineShaderStageCreateInfo()
            .setStage(vk::ShaderStageFlagBits::eFragment)
            .setModule(FragmentShader->Module)
            .setPName("main");

        vk::PipelineVertexInputStateCreateInfo PipelineVertexInputStateCreateInfo=vk::PipelineVertexInputStateCreateInfo()
            .setVertexBindingDescriptionCount(0)
            .setVertexAttributeDescriptionCount(0);

        vk::PipelineInputAssemblyStateCreateInfo PipelineInputAssemblyStateCreateInfo=vk::PipelineInputAssemblyStateCreateInfo()
            .setTopology(vk::PrimitiveTopology::eTriangleStrip);

        vk::PipelineViewportStateCreateInfo PipelineViewportStateCreateInfo=vk::PipelineViewportStateCreateInfo()
            .setViewportCount(1)
            .setScissorCount(1);

        vk::PipelineRasterizationStateCreateInfo PipelineRasterizationStateCreateInfo=vk::PipelineRasterizationStateCreateInfo()
            .setPolygonMode(vk::PolygonMode::eFill)
            .setCullMode(vk::CullModeFlagBits::eNone)
            .setFrontFace(vk::FrontFace::eClockwise)
            .setLineWidth(1.0f);

        vk::PipelineMultisampleStateCreateInfo PipelineMultisampleStateCreateInfo=vk::PipelineMultisampleStateCreateInfo()
            .setRasterizationSamples(vk::SampleCountFlagBits::e1);

        vk::PipelineDepthStencilStateCreateInfo PipelineDepthStencilStateCreateInfo=vk::PipelineDepthStencilStateCreateInfo()
            .setDepthTestEnable(false)
            .setDepthWriteEnable(false)
            .setDepthCompareOp(vk::CompareOp::eLessOrEqual)
            .setDepthBoundsTestEnable(false)
            .setStencilTestEnable(false);

        vk::PipelineColorBlendAttachmentState PipelineColorBlendAttachmentState=vk::PipelineColorBlendAttachmentState()
                .setColorWriteMask(
                    vk::ColorComponentFlagBits::eR
                    |vk::ColorComponentFlagBits::eG
                    |vk::ColorComponentFlagBits::eB
                    |vk::ColorComponentFlagBits::eA
                )
                .setBlendEnable(true)
                .setSrcColorBlendFactor(vk::BlendFactor::eOne)
                .setDstColorBlendFactor(vk::BlendFactor::eOne)
                .setColorBlendOp(vk::BlendOp::eAdd)     //just add color with both weight is 1
                .setSrcAlphaBlendFactor(vk::BlendFactor::eOne)
                .setDstAlphaBlendFactor(vk::BlendFactor::eZero)
                .setAlphaBlendOp(vk::BlendOp::eAdd)
                
        ;

        vk::PipelineColorBlendStateCreateInfo PipelineColorBlendStateCreateInfo=vk::PipelineColorBlendStateCreateInfo()
            .setAttachmentCount(1)
            .setPAttachments(&PipelineColorBlendAttachmentState);

        vk::GraphicsPipelineCreateInfo GraphicsPipelineCreateInfo=vk::GraphicsPipelineCreateInfo()
            .setPDynamicState(&PipelineDynamicStateCreateInfo)
            .setStageCount(2)
            .setPStages(PipelineShaderStageCreateInfo)
            .setPVertexInputState(&PipelineVertexInputStateCreateInfo)
            .setPInputAssemblyState(&PipelineInputAssemblyStateCreateInfo)
            .setPViewportState(&PipelineViewportStateCreateInfo)
            .setPRasterizationState(&PipelineRasterizationStateCreateInfo)
            .setPMultisampleState(&PipelineMultisampleStateCreateInfo)
            .setPDepthStencilState(&PipelineDepthStencilStateCreateInfo)
            .setPColorBlendState(&PipelineColorBlendStateCreateInfo)
            .setLayout(SpotLightDefferShadingPipelineLayout)
            .setRenderPass(SceneRenderPass)
            .setSubpass(1);

        SpotLightDefferShadingPipeline=CVulkanContext::Get()->GetDevice().createGraphicsPipeline(nullptr,GraphicsPipelineCreateInfo).value;
    }

    //create Point light deffer shading pipeline
    {
        TVector<vk::DescriptorSetLayoutBinding> DescriptorSetLayoutBindings=
        {
            //shadow map
            vk::DescriptorSetLayoutBinding()
                .setBinding(0)
                .setDescriptorType(vk::DescriptorType::eCombinedImageSampler)
                .setDescriptorCount(1)
                .setStageFlags(vk::ShaderStageFlagBits::eFragment)
                .setPImmutableSamplers(nullptr)
        };


        vk::DescriptorSetLayoutCreateInfo DescriptorSetLayoutCreateInfo = vk::DescriptorSetLayoutCreateInfo()
            .setBindings(DescriptorSetLayoutBindings);

        PointLightDefferShadingDescriptorSetLayout.Layout =CVulkanContext::Get()->GetDevice().createDescriptorSetLayout(DescriptorSetLayoutCreateInfo);
        PointLightDefferShadingDescriptorSetLayout.DescriptorNums.CombinedImageSamplerDescriptorNum=1;

        //create pipeline layout, use a push constant for the camera position and light info
        TVector<vk::PushConstantRange> PushConstantRanges=
        {
            vk::PushConstantRange()
            .setStageFlags(vk::ShaderStageFlagBits::eFragment)
            .setOffset(0)
            .setSize(sizeof(SPointLightDefferShadingFragmentPushConstant))
            ,
        };

        TVector<vk::DescriptorSetLayout> DescriptorSetLayouts=
        {
            DefferShadingDescriptorSetLayout.Layout,
            PointLightDefferShadingDescriptorSetLayout.Layout
        };

        vk::PipelineLayoutCreateInfo PipelineLayoutCreateInfo = vk::PipelineLayoutCreateInfo()
            .setSetLayouts(DescriptorSetLayouts)
            .setPushConstantRanges(PushConstantRanges);

        PointLightDefferShadingPipelineLayout =CVulkanContext::Get()->GetDevice().createPipelineLayout(PipelineLayoutCreateInfo);

        //create pipeline
        auto VertexShader= CVulkanContext::Get()->GetShaderManager()->GetVulkanOnlyShader(U"DefferShadingVertex");
        auto FragmentShader= CVulkanContext::Get()->GetShaderManager()->GetVulkanOnlyShader(U"PointLightDefferShadingFragment");

        //dynamic state
        vk::DynamicState DynamicState[2]={vk::DynamicState::eViewport,vk::DynamicState::eScissor};

        vk::PipelineDynamicStateCreateInfo PipelineDynamicStateCreateInfo=vk::PipelineDynamicStateCreateInfo()
            .setDynamicStateCount(2)
            .setPDynamicStates(DynamicState);

        vk::PipelineShaderStageCreateInfo PipelineShaderStageCreateInfo[2];
        PipelineShaderStageCreateInfo[0]=vk::PipelineShaderStageCreateInfo()
            .setStage(vk::ShaderStageFlagBits::eVertex)
            .setModule(VertexShader->Module)
            .setPName("main");

        PipelineShaderStageCreateInfo[1]=vk::PipelineShaderStageCreateInfo()
            .setStage(vk::ShaderStageFlagBits::eFragment)
            .setModule(FragmentShader->Module)
            .setPName("main");

        vk::PipelineVertexInputStateCreateInfo PipelineVertexInputStateCreateInfo=vk::PipelineVertexInputStateCreateInfo()
            .setVertexBindingDescriptionCount(0)
            .setVertexAttributeDescriptionCount(0);

        vk::PipelineInputAssemblyStateCreateInfo PipelineInputAssemblyStateCreateInfo=vk::PipelineInputAssemblyStateCreateInfo()
            .setTopology(vk::PrimitiveTopology::eTriangleStrip);

        vk::PipelineViewportStateCreateInfo PipelineViewportStateCreateInfo=vk::PipelineViewportStateCreateInfo()
            .setViewportCount(1)
            .setScissorCount(1);

        vk::PipelineRasterizationStateCreateInfo PipelineRasterizationStateCreateInfo=vk::PipelineRasterizationStateCreateInfo()
            .setPolygonMode(vk::PolygonMode::eFill)
            .setCullMode(vk::CullModeFlagBits::eNone)
            .setFrontFace(vk::FrontFace::eClockwise)
            .setLineWidth(1.0f);

        vk::PipelineMultisampleStateCreateInfo PipelineMultisampleStateCreateInfo=vk::PipelineMultisampleStateCreateInfo()
            .setRasterizationSamples(vk::SampleCountFlagBits::e1);

        vk::PipelineDepthStencilStateCreateInfo PipelineDepthStencilStateCreateInfo=vk::PipelineDepthStencilStateCreateInfo()
            .setDepthTestEnable(false)
            .setDepthWriteEnable(false)
            .setDepthCompareOp(vk::CompareOp::eLessOrEqual)
            .setDepthBoundsTestEnable(false)
            .setStencilTestEnable(false);

        vk::PipelineColorBlendAttachmentState PipelineColorBlendAttachmentState=vk::PipelineColorBlendAttachmentState()
                .setColorWriteMask(
                    vk::ColorComponentFlagBits::eR
                    |vk::ColorComponentFlagBits::eG
                    |vk::ColorComponentFlagBits::eB
                    |vk::ColorComponentFlagBits::eA
                )
                .setBlendEnable(true)
                .setSrcColorBlendFactor(vk::BlendFactor::eOne)
                .setDstColorBlendFactor(vk::BlendFactor::eOne)
                .setColorBlendOp(vk::BlendOp::eAdd)     //just add color with both weight is 1
                .setSrcAlphaBlendFactor(vk::BlendFactor::eOne)
                .setDstAlphaBlendFactor(vk::BlendFactor::eZero)
                .setAlphaBlendOp(vk::BlendOp::eAdd)

        ;   

        vk::PipelineColorBlendStateCreateInfo PipelineColorBlendStateCreateInfo=vk::PipelineColorBlendStateCreateInfo()
            .setAttachmentCount(1)
            .setPAttachments(&PipelineColorBlendAttachmentState);

        vk::GraphicsPipelineCreateInfo GraphicsPipelineCreateInfo=vk::GraphicsPipelineCreateInfo()
            .setPDynamicState(&PipelineDynamicStateCreateInfo)
            .setStageCount(2)
            .setPStages(PipelineShaderStageCreateInfo)
            .setPVertexInputState(&PipelineVertexInputStateCreateInfo)
            .setPInputAssemblyState(&PipelineInputAssemblyStateCreateInfo)
            .setPViewportState(&PipelineViewportStateCreateInfo)
            .setPRasterizationState(&PipelineRasterizationStateCreateInfo)
            .setPMultisampleState(&PipelineMultisampleStateCreateInfo)
            .setPDepthStencilState(&PipelineDepthStencilStateCreateInfo)
            .setPColorBlendState(&PipelineColorBlendStateCreateInfo)
            .setLayout(PointLightDefferShadingPipelineLayout)
            .setRenderPass(SceneRenderPass)
            .setSubpass(1);

        PointLightDefferShadingPipeline=CVulkanContext::Get()->GetDevice().createGraphicsPipeline(nullptr,GraphicsPipelineCreateInfo).value;
    }

    //create directional light deffer shading pipeline
    {
        TVector<vk::DescriptorSetLayoutBinding> DescriptorSetLayoutBindings=
        {
            //shadow maps
            vk::DescriptorSetLayoutBinding()
                .setBinding(0)
                .setDescriptorType(vk::DescriptorType::eCombinedImageSampler)
                .setDescriptorCount(GetCascadeNum())
                .setStageFlags(vk::ShaderStageFlagBits::eFragment)
                .setPImmutableSamplers(nullptr)

            //uniform buffer
            ,vk::DescriptorSetLayoutBinding()
                .setBinding(1)
                .setDescriptorType(vk::DescriptorType::eUniformBuffer)
                .setDescriptorCount(1)
                .setStageFlags(vk::ShaderStageFlagBits::eFragment)
                .setPImmutableSamplers(nullptr)
        };

        vk::DescriptorSetLayoutCreateInfo DescriptorSetLayoutCreateInfo  = vk::DescriptorSetLayoutCreateInfo()
            .setBindings(DescriptorSetLayoutBindings);
        
        DirectionalLightDefferShadingDescriptorSetLayout.Layout =CVulkanContext::Get()->GetDevice().createDescriptorSetLayout(DescriptorSetLayoutCreateInfo);
        DirectionalLightDefferShadingDescriptorSetLayout.DescriptorNums.CombinedImageSamplerDescriptorNum=GetCascadeNum();
        DirectionalLightDefferShadingDescriptorSetLayout.DescriptorNums.UniformBufferDescriptorNum=1;

        TVector<vk::DescriptorSetLayout> DescriptorSetLayouts=
        {
            DefferShadingDescriptorSetLayout.Layout,
            DirectionalLightDefferShadingDescriptorSetLayout.Layout
        };

        vk::PipelineLayoutCreateInfo PipelineLayoutCreateInfo = vk::PipelineLayoutCreateInfo()
            .setSetLayouts(DescriptorSetLayouts)
            ;

        DirectionalLightDefferShadingPipelineLayout =CVulkanContext::Get()->GetDevice().createPipelineLayout(PipelineLayoutCreateInfo);

        //create pipeline
        auto VertexShader= CVulkanContext::Get()->GetShaderManager()->GetVulkanOnlyShader(U"DefferShadingVertex");
        auto FragmentShader= CVulkanContext::Get()->GetShaderManager()->GetVulkanOnlyShader(U"DirectionalLightDefferShadingFragment");

        //dynamic state
        vk::DynamicState DynamicState[2]={vk::DynamicState::eViewport,vk::DynamicState::eScissor};

        vk::PipelineDynamicStateCreateInfo PipelineDynamicStateCreateInfo=vk::PipelineDynamicStateCreateInfo()
            .setDynamicStateCount(2)
            .setPDynamicStates(DynamicState);

        vk::PipelineShaderStageCreateInfo PipelineShaderStageCreateInfo[2];
        PipelineShaderStageCreateInfo[0]=vk::PipelineShaderStageCreateInfo()
            .setStage(vk::ShaderStageFlagBits::eVertex)
            .setModule(VertexShader->Module)
            .setPName("main");

        PipelineShaderStageCreateInfo[1]=vk::PipelineShaderStageCreateInfo()
            .setStage(vk::ShaderStageFlagBits::eFragment)
            .setModule(FragmentShader->Module)
            .setPName("main");


        vk::PipelineVertexInputStateCreateInfo PipelineVertexInputStateCreateInfo=vk::PipelineVertexInputStateCreateInfo()
            .setVertexBindingDescriptionCount(0)
            .setVertexAttributeDescriptionCount(0);

        vk::PipelineInputAssemblyStateCreateInfo PipelineInputAssemblyStateCreateInfo=vk::PipelineInputAssemblyStateCreateInfo()
            .setTopology(vk::PrimitiveTopology::eTriangleStrip);

        vk::PipelineViewportStateCreateInfo PipelineViewportStateCreateInfo=vk::PipelineViewportStateCreateInfo()
            .setViewportCount(1)
            .setScissorCount(1);

        vk::PipelineRasterizationStateCreateInfo PipelineRasterizationStateCreateInfo=vk::PipelineRasterizationStateCreateInfo()
            .setPolygonMode(vk::PolygonMode::eFill)
            .setCullMode(vk::CullModeFlagBits::eNone)
            .setFrontFace(vk::FrontFace::eClockwise)
            .setLineWidth(1.0f);

        vk::PipelineMultisampleStateCreateInfo PipelineMultisampleStateCreateInfo=vk::PipelineMultisampleStateCreateInfo()
            .setRasterizationSamples(vk::SampleCountFlagBits::e1);

        vk::PipelineDepthStencilStateCreateInfo PipelineDepthStencilStateCreateInfo=vk::PipelineDepthStencilStateCreateInfo()
            .setDepthTestEnable(false)
            .setDepthWriteEnable(false)
            .setDepthCompareOp(vk::CompareOp::eLessOrEqual)
            .setDepthBoundsTestEnable(false)
            .setStencilTestEnable(false);

        vk::PipelineColorBlendAttachmentState PipelineColorBlendAttachmentState=vk::PipelineColorBlendAttachmentState()
                .setColorWriteMask(
                    vk::ColorComponentFlagBits::eR
                    |vk::ColorComponentFlagBits::eG
                    |vk::ColorComponentFlagBits::eB
                    |vk::ColorComponentFlagBits::eA
                )
                .setBlendEnable(true)
                .setSrcColorBlendFactor(vk::BlendFactor::eOne)
                .setDstColorBlendFactor(vk::BlendFactor::eOne)
                .setColorBlendOp(vk::BlendOp::eAdd)     //just add color with both weight is 1
                .setSrcAlphaBlendFactor(vk::BlendFactor::eOne)
                .setDstAlphaBlendFactor(vk::BlendFactor::eZero)
                .setAlphaBlendOp(vk::BlendOp::eAdd)

        ;

        vk::PipelineColorBlendStateCreateInfo PipelineColorBlendStateCreateInfo=vk::PipelineColorBlendStateCreateInfo()
            .setAttachmentCount(1)
            .setPAttachments(&PipelineColorBlendAttachmentState);

        vk::GraphicsPipelineCreateInfo GraphicsPipelineCreateInfo=vk::GraphicsPipelineCreateInfo()
            .setPDynamicState(&PipelineDynamicStateCreateInfo)
            .setStageCount(2)
            .setPStages(PipelineShaderStageCreateInfo)
            .setPVertexInputState(&PipelineVertexInputStateCreateInfo)
            .setPInputAssemblyState(&PipelineInputAssemblyStateCreateInfo)
            .setPViewportState(&PipelineViewportStateCreateInfo)
            .setPRasterizationState(&PipelineRasterizationStateCreateInfo)
            .setPMultisampleState(&PipelineMultisampleStateCreateInfo)
            .setPDepthStencilState(&PipelineDepthStencilStateCreateInfo)
            .setPColorBlendState(&PipelineColorBlendStateCreateInfo)
            .setLayout(DirectionalLightDefferShadingPipelineLayout)
            .setRenderPass(SceneRenderPass)
            .setSubpass(1);

        DirectionalLightDefferShadingPipeline=CVulkanContext::Get()->GetDevice().createGraphicsPipeline(nullptr,GraphicsPipelineCreateInfo).value;

    }

    //环境光照
    {
        //仅需要推送常量
        TVector<vk::PushConstantRange> PushConstantRanges=
        {
            vk::PushConstantRange()
            .setStageFlags(vk::ShaderStageFlagBits::eFragment)
            .setOffset(0)
            .setSize(sizeof(SAmbientLightDefferShadingFragmentPushConstant))
            ,
        };

        TVector<vk::DescriptorSetLayout> DescriptorSetLayouts=
        {
            DefferShadingDescriptorSetLayout.Layout
        };

        vk::PipelineLayoutCreateInfo PipelineLayoutCreateInfo = vk::PipelineLayoutCreateInfo()
            .setSetLayouts(DescriptorSetLayouts)
            .setPushConstantRanges(PushConstantRanges);
        
        AmbientLightDefferShadingPipelineLayout =CVulkanContext::Get()->GetDevice().createPipelineLayout(PipelineLayoutCreateInfo);

        //创建管线
        auto VertexShader= CVulkanContext::Get()->GetShaderManager()->GetVulkanOnlyShader(U"AmbientLight_vert");
        auto FragmentShader= CVulkanContext::Get()->GetShaderManager()->GetVulkanOnlyShader(U"AmbientLight_frag");

        //dynamic state
        vk::DynamicState DynamicState[2]={vk::DynamicState::eViewport,vk::DynamicState::eScissor};

        vk::PipelineDynamicStateCreateInfo PipelineDynamicStateCreateInfo=vk::PipelineDynamicStateCreateInfo()
            .setDynamicStateCount(2)
            .setPDynamicStates(DynamicState);

        vk::PipelineShaderStageCreateInfo PipelineShaderStageCreateInfo[2];
        PipelineShaderStageCreateInfo[0]=vk::PipelineShaderStageCreateInfo()
            .setStage(vk::ShaderStageFlagBits::eVertex)
            .setModule(VertexShader->Module)
            .setPName("main");

        PipelineShaderStageCreateInfo[1]=vk::PipelineShaderStageCreateInfo()
            .setStage(vk::ShaderStageFlagBits::eFragment)
            .setModule(FragmentShader->Module)
            .setPName("main");

        vk::PipelineVertexInputStateCreateInfo PipelineVertexInputStateCreateInfo=vk::PipelineVertexInputStateCreateInfo()
            .setVertexBindingDescriptionCount(0)
            .setVertexAttributeDescriptionCount(0);

        vk::PipelineInputAssemblyStateCreateInfo PipelineInputAssemblyStateCreateInfo=vk::PipelineInputAssemblyStateCreateInfo()
            .setTopology(vk::PrimitiveTopology::eTriangleStrip);

        vk::PipelineViewportStateCreateInfo PipelineViewportStateCreateInfo=vk::PipelineViewportStateCreateInfo()
            .setViewportCount(1)
            .setScissorCount(1);

        vk::PipelineRasterizationStateCreateInfo PipelineRasterizationStateCreateInfo=vk::PipelineRasterizationStateCreateInfo()
            .setPolygonMode(vk::PolygonMode::eFill)
            .setCullMode(vk::CullModeFlagBits::eNone)
            .setFrontFace(vk::FrontFace::eClockwise)
            .setLineWidth(1.0f);

        vk::PipelineMultisampleStateCreateInfo PipelineMultisampleStateCreateInfo=vk::PipelineMultisampleStateCreateInfo()
            .setRasterizationSamples(vk::SampleCountFlagBits::e1);

        vk::PipelineDepthStencilStateCreateInfo PipelineDepthStencilStateCreateInfo=vk::PipelineDepthStencilStateCreateInfo()
            .setDepthTestEnable(false)
            .setDepthWriteEnable(false)
            .setDepthCompareOp(vk::CompareOp::eLessOrEqual)
            .setDepthBoundsTestEnable(false)
            .setStencilTestEnable(false);

        vk::PipelineColorBlendAttachmentState PipelineColorBlendAttachmentState=vk::PipelineColorBlendAttachmentState()
                .setColorWriteMask(
                    vk::ColorComponentFlagBits::eR
                    |vk::ColorComponentFlagBits::eG
                    |vk::ColorComponentFlagBits::eB
                    |vk::ColorComponentFlagBits::eA
                )
                .setBlendEnable(true)
                .setSrcColorBlendFactor(vk::BlendFactor::eOne)
                .setDstColorBlendFactor(vk::BlendFactor::eOne)
                .setColorBlendOp(vk::BlendOp::eAdd)     //just add color with both weight is 1
                .setSrcAlphaBlendFactor(vk::BlendFactor::eOne)
                .setDstAlphaBlendFactor(vk::BlendFactor::eZero)
                .setAlphaBlendOp(vk::BlendOp::eAdd);

        vk::PipelineColorBlendStateCreateInfo PipelineColorBlendStateCreateInfo=vk::PipelineColorBlendStateCreateInfo()
            .setAttachmentCount(1)
            .setPAttachments(&PipelineColorBlendAttachmentState);

        vk::GraphicsPipelineCreateInfo GraphicsPipelineCreateInfo=vk::GraphicsPipelineCreateInfo()
            .setPDynamicState(&PipelineDynamicStateCreateInfo)
            .setStageCount(2)
            .setPStages(PipelineShaderStageCreateInfo)
            .setPVertexInputState(&PipelineVertexInputStateCreateInfo)
            .setPInputAssemblyState(&PipelineInputAssemblyStateCreateInfo)
            .setPViewportState(&PipelineViewportStateCreateInfo)
            .setPRasterizationState(&PipelineRasterizationStateCreateInfo)
            .setPMultisampleState(&PipelineMultisampleStateCreateInfo)
            .setPDepthStencilState(&PipelineDepthStencilStateCreateInfo)
            .setPColorBlendState(&PipelineColorBlendStateCreateInfo)
            .setLayout(AmbientLightDefferShadingPipelineLayout)
            .setRenderPass(SceneRenderPass)
            .setSubpass(1);

        AmbientLightDefferShadingPipeline=CVulkanContext::Get()->GetDevice().createGraphicsPipeline(nullptr,GraphicsPipelineCreateInfo).value;
        
    }
}

void CSceneGlobal::CreatePointLightShadowMapThings()
{

    vk::AttachmentDescription AttachmentDescriptions[2]=
    {   
        //阴影贴图,只有一个通道
        vk::AttachmentDescription()
            .setFormat(PointLightShadowMapImageFormat)
            .setSamples(vk::SampleCountFlagBits::e1)
            .setLoadOp(vk::AttachmentLoadOp::eClear)
            .setStoreOp(vk::AttachmentStoreOp::eStore)
            .setStencilLoadOp(vk::AttachmentLoadOp::eDontCare)
            .setStencilStoreOp(vk::AttachmentStoreOp::eDontCare)
            .setInitialLayout(vk::ImageLayout::eUndefined)
            .setFinalLayout(vk::ImageLayout::eColorAttachmentOptimal)
        ,

        //深度，用于深度测试，不是阴影贴图
        vk::AttachmentDescription()
            .setFormat(vk::Format::eD16Unorm)
            .setSamples(vk::SampleCountFlagBits::e1)
            .setLoadOp(vk::AttachmentLoadOp::eClear)
            .setStoreOp(vk::AttachmentStoreOp::eStore)
            .setStencilLoadOp(vk::AttachmentLoadOp::eDontCare)
            .setStencilStoreOp(vk::AttachmentStoreOp::eDontCare)
            .setInitialLayout(vk::ImageLayout::eUndefined)
            .setFinalLayout(vk::ImageLayout::eDepthStencilAttachmentOptimal)
    };

    vk::AttachmentReference ColorReference=vk::AttachmentReference()
        .setAttachment(0)
        .setLayout(vk::ImageLayout::eColorAttachmentOptimal);

    vk::AttachmentReference DepthReference=vk::AttachmentReference()
        .setAttachment(1)
        .setLayout(vk::ImageLayout::eDepthStencilAttachmentOptimal);

    vk::SubpassDescription SubpassDescription=vk::SubpassDescription()
        .setPipelineBindPoint(vk::PipelineBindPoint::eGraphics)
        .setInputAttachmentCount(0)
        .setPInputAttachments(nullptr)
        .setColorAttachmentCount(1)
        .setPColorAttachments(&ColorReference)
        .setPResolveAttachments(nullptr)
        .setPDepthStencilAttachment(&DepthReference)
        .setPreserveAttachmentCount(0)
        .setPPreserveAttachments(nullptr);

    vk::RenderPassCreateInfo RenderPassCreateInfo=vk::RenderPassCreateInfo()
        .setAttachmentCount(2)
        .setPAttachments(AttachmentDescriptions)
        .setSubpassCount(1)
        .setPSubpasses(&SubpassDescription);

    PointLightShadowMapRenderPass=CVulkanContext::Get()->GetDevice().createRenderPass(RenderPassCreateInfo);

    //创建描述符布局
    //有两个buffer
    //一个是光源的view matrix 和 projection matrix 
    //一个是模型的model matrix

    TVector<vk::DescriptorSetLayoutBinding> DescriptorSetLayoutBindings={
        //光源的view matrix 和 projection matrix
        vk::DescriptorSetLayoutBinding()
            .setBinding(0)
            .setDescriptorType(vk::DescriptorType::eUniformBuffer)
            .setDescriptorCount(1)
            .setStageFlags(vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment)
        ,

        //模型的矩阵
        vk::DescriptorSetLayoutBinding()
            .setBinding(1)
            .setDescriptorType(vk::DescriptorType::eUniformBuffer)
            .setDescriptorCount(1)
            .setStageFlags(vk::ShaderStageFlagBits::eVertex )

    };

    vk::DescriptorSetLayoutCreateInfo DescriptorSetLayoutCreateInfo = vk::DescriptorSetLayoutCreateInfo()
        .setBindings(DescriptorSetLayoutBindings);

    PointLightShadowMapDescriptorSetLayout.Layout =CVulkanContext::Get()->GetDevice().createDescriptorSetLayout(DescriptorSetLayoutCreateInfo);
    PointLightShadowMapDescriptorSetLayout.DescriptorNums.UniformBufferDescriptorNum=2;


    //创建管线布局
    TVector<vk::DescriptorSetLayout> DescriptorSetLayouts=
    {
        PointLightShadowMapDescriptorSetLayout.Layout,
        ModelDescriptorSetLayout.Layout
    };

    vk::PipelineLayoutCreateInfo PipelineLayoutCreateInfo=vk::PipelineLayoutCreateInfo()
        .setSetLayouts(DescriptorSetLayouts);
       
    PointLightShadowMapPipelineLayout=CVulkanContext::Get()->GetDevice().createPipelineLayout(PipelineLayoutCreateInfo);

    PointLightShadowMapExtent=vk::Extent2D(2048,2048);

    //创建管线
    auto VertexShader= CVulkanContext::Get()->GetShaderManager()->GetVulkanOnlyShader(U"PointLightShadowMap_vert");  
    auto FragmentShader= CVulkanContext::Get()->GetShaderManager()->GetVulkanOnlyShader(U"PointLightShadowMap_frag");

    vk::PipelineShaderStageCreateInfo PipelineShaderStageCreateInfo[2]={
        vk::PipelineShaderStageCreateInfo()
            .setStage(vk::ShaderStageFlagBits::eVertex)
            .setModule(VertexShader->Module)
            .setPName("main"),
        vk::PipelineShaderStageCreateInfo()
            .setStage(vk::ShaderStageFlagBits::eFragment)
            .setModule(FragmentShader->Module)
            .setPName("main")
    };

    //only use mesh position 
    vk::VertexInputAttributeDescription VertexInputAttributeDescription=vk::VertexInputAttributeDescription()
        .setBinding(0)
        .setLocation(0)
        .setFormat(vk::Format::eR32G32B32Sfloat)
        .setOffset(offsetof(SVertex,Position));

    auto VertexInputBindingDescriptions=CVulkanContext::Get()->GetMeshVertexInputBindingDescriptions();

    vk::PipelineVertexInputStateCreateInfo PipelineVertexInputStateCreateInfo=vk::PipelineVertexInputStateCreateInfo()
        .setVertexBindingDescriptionCount(1)
        .setPVertexBindingDescriptions(VertexInputBindingDescriptions.Data())
        .setVertexAttributeDescriptionCount(1)
        .setPVertexAttributeDescriptions(&VertexInputAttributeDescription);


    vk::PipelineInputAssemblyStateCreateInfo PipelineInputAssemblyStateCreateInfo=vk::PipelineInputAssemblyStateCreateInfo()
        .setTopology(vk::PrimitiveTopology::eTriangleList)
        .setPrimitiveRestartEnable(false);

    PointLightShadowMapExtent=vk::Extent2D(2048,2048);

    vk::Viewport Viewport=vk::Viewport()
        .setX(0)
        .setY(0)
        .setWidth(PointLightShadowMapExtent.width)
        .setHeight(PointLightShadowMapExtent.height)
        .setMinDepth(0)
        .setMaxDepth(1);

    vk::Rect2D Scissor=vk::Rect2D()
        .setOffset(vk::Offset2D(0,0))
        .setExtent(PointLightShadowMapExtent);

    vk::PipelineViewportStateCreateInfo PipelineViewportStateCreateInfo=vk::PipelineViewportStateCreateInfo()
        .setViewportCount(1)
        .setPViewports(&Viewport)
        .setScissorCount(1)
        .setPScissors(&Scissor);
        ;
    
    vk::PipelineRasterizationStateCreateInfo PipelineRasterizationStateCreateInfo=vk::PipelineRasterizationStateCreateInfo()
        .setDepthClampEnable(false)
        .setRasterizerDiscardEnable(false)
        .setPolygonMode(vk::PolygonMode::eFill)
        .setCullMode(vk::CullModeFlagBits::eBack)
        .setFrontFace(vk::FrontFace::eCounterClockwise)
        .setDepthBiasEnable(false)
        .setDepthBiasConstantFactor(0)
        .setDepthBiasClamp(0)
        .setDepthBiasSlopeFactor(0)
        .setLineWidth(1);

    vk::PipelineMultisampleStateCreateInfo PipelineMultisampleStateCreateInfo=vk::PipelineMultisampleStateCreateInfo()
        .setRasterizationSamples(vk::SampleCountFlagBits::e1)
        .setSampleShadingEnable(false)
        .setMinSampleShading(0)
        .setPSampleMask(nullptr)
        .setAlphaToCoverageEnable(false)
        .setAlphaToOneEnable(false);

    vk::PipelineDepthStencilStateCreateInfo PipelineDepthStencilStateCreateInfo=vk::PipelineDepthStencilStateCreateInfo()
        .setDepthTestEnable(true)
        .setDepthWriteEnable(true)
        .setDepthCompareOp(vk::CompareOp::eLess)
        .setDepthBoundsTestEnable(false)
        .setStencilTestEnable(false);

    vk::PipelineColorBlendAttachmentState PipelineColorBlendAttachmentState=vk::PipelineColorBlendAttachmentState()
        .setColorWriteMask(
            vk::ColorComponentFlagBits::eR
            |vk::ColorComponentFlagBits::eG
            |vk::ColorComponentFlagBits::eB
            |vk::ColorComponentFlagBits::eA
        )
        .setBlendEnable(false)
        .setSrcColorBlendFactor(vk::BlendFactor::eOne)
        .setDstColorBlendFactor(vk::BlendFactor::eOne)
        .setColorBlendOp(vk::BlendOp::eAdd)     //just add color with both weight is 1
        .setSrcAlphaBlendFactor(vk::BlendFactor::eOne)
        .setDstAlphaBlendFactor(vk::BlendFactor::eZero)
        .setAlphaBlendOp(vk::BlendOp::eAdd);

    vk::PipelineColorBlendStateCreateInfo PipelineColorBlendStateCreateInfo=vk::PipelineColorBlendStateCreateInfo()
        .setAttachmentCount(1)
        .setPAttachments(&PipelineColorBlendAttachmentState);

    vk::GraphicsPipelineCreateInfo GraphicsPipelineCreateInfo=vk::GraphicsPipelineCreateInfo()
        .setStages(PipelineShaderStageCreateInfo)
        .setPVertexInputState(&PipelineVertexInputStateCreateInfo)
        .setPInputAssemblyState(&PipelineInputAssemblyStateCreateInfo)
        .setPViewportState(&PipelineViewportStateCreateInfo)
        .setPRasterizationState(&PipelineRasterizationStateCreateInfo)
        .setPMultisampleState(&PipelineMultisampleStateCreateInfo)
        .setPDepthStencilState(&PipelineDepthStencilStateCreateInfo)
        .setPColorBlendState(&PipelineColorBlendStateCreateInfo)
        .setPDynamicState(nullptr)
        .setLayout(PointLightShadowMapPipelineLayout)
        .setRenderPass(PointLightShadowMapRenderPass)
        .setSubpass(0);

    PointLightShadowMapPipeline=CVulkanContext::Get()->GetDevice().createGraphicsPipeline(nullptr,GraphicsPipelineCreateInfo).value;

}

void CSceneGlobal::CreateSpotLightShadowMapThings()
{
    vk::AttachmentDescription AttachmentDescriptions[2]=
    {   
        //阴影贴图,只有一个通道
        vk::AttachmentDescription()
            .setFormat(SpotLightShadowMapImageFormat)
            .setSamples(vk::SampleCountFlagBits::e1)
            .setLoadOp(vk::AttachmentLoadOp::eClear)
            .setStoreOp(vk::AttachmentStoreOp::eStore)
            .setStencilLoadOp(vk::AttachmentLoadOp::eDontCare)
            .setStencilStoreOp(vk::AttachmentStoreOp::eDontCare)
            .setInitialLayout(vk::ImageLayout::eUndefined)
            .setFinalLayout(vk::ImageLayout::eColorAttachmentOptimal)
        ,

        //深度，用于深度测试，不是阴影贴图
        vk::AttachmentDescription()
            .setFormat(vk::Format::eD16Unorm)
            .setSamples(vk::SampleCountFlagBits::e1)
            .setLoadOp(vk::AttachmentLoadOp::eClear)
            .setStoreOp(vk::AttachmentStoreOp::eStore)
            .setStencilLoadOp(vk::AttachmentLoadOp::eDontCare)
            .setStencilStoreOp(vk::AttachmentStoreOp::eDontCare)
            .setInitialLayout(vk::ImageLayout::eUndefined)
            .setFinalLayout(vk::ImageLayout::eDepthStencilAttachmentOptimal)
    };

    vk::AttachmentReference ColorReference=vk::AttachmentReference()
        .setAttachment(0)
        .setLayout(vk::ImageLayout::eColorAttachmentOptimal);

    vk::AttachmentReference DepthReference=vk::AttachmentReference()
        .setAttachment(1)
        .setLayout(vk::ImageLayout::eDepthStencilAttachmentOptimal);

    vk::SubpassDescription SubpassDescription=vk::SubpassDescription()
        .setPipelineBindPoint(vk::PipelineBindPoint::eGraphics)
        .setInputAttachmentCount(0)
        .setPInputAttachments(nullptr)
        .setColorAttachmentCount(1)
        .setPColorAttachments(&ColorReference)
        .setPResolveAttachments(nullptr)
        .setPDepthStencilAttachment(&DepthReference)
        .setPreserveAttachmentCount(0)
        .setPPreserveAttachments(nullptr);

    vk::RenderPassCreateInfo RenderPassCreateInfo=vk::RenderPassCreateInfo()
        .setAttachmentCount(2)
        .setPAttachments(AttachmentDescriptions)
        .setSubpassCount(1)
        .setPSubpasses(&SubpassDescription);

    SpotLightShadowMapRenderPass=CVulkanContext::Get()->GetDevice().createRenderPass(RenderPassCreateInfo);

    //创建描述符布局
    //有两个buffer
    //一个是光源的view matrix 和 projection matrix
    //一个是模型的model matrix

    TVector<vk::DescriptorSetLayoutBinding> DescriptorSetLayoutBindings={
        vk::DescriptorSetLayoutBinding()
            .setBinding(0)
            .setDescriptorType(vk::DescriptorType::eUniformBuffer)
            .setDescriptorCount(1)
            .setStageFlags(vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment)
        ,
        vk::DescriptorSetLayoutBinding()
            .setBinding(1)
            .setDescriptorType(vk::DescriptorType::eUniformBuffer)
            .setDescriptorCount(1)
            .setStageFlags(vk::ShaderStageFlagBits::eVertex)

    };

    vk::DescriptorSetLayoutCreateInfo DescriptorSetLayoutCreateInfo = vk::DescriptorSetLayoutCreateInfo()
        .setBindings(DescriptorSetLayoutBindings);

    SpotLightShadowMapDescriptorSetLayout.Layout =CVulkanContext::Get()->GetDevice().createDescriptorSetLayout(DescriptorSetLayoutCreateInfo);
    SpotLightShadowMapDescriptorSetLayout.DescriptorNums.UniformBufferDescriptorNum=2;

    //创建管线布局
    TVector<vk::DescriptorSetLayout> DescriptorSetLayouts=
    {
        SpotLightShadowMapDescriptorSetLayout.Layout,
        ModelDescriptorSetLayout.Layout
    };

    vk::PipelineLayoutCreateInfo PipelineLayoutCreateInfo=vk::PipelineLayoutCreateInfo()
        .setSetLayouts(DescriptorSetLayouts);

    SpotLightShadowMapPipelineLayout=CVulkanContext::Get()->GetDevice().createPipelineLayout(PipelineLayoutCreateInfo);


    //创建管线
    auto VertexShader= CVulkanContext::Get()->GetShaderManager()->GetVulkanOnlyShader(U"PointLightShadowMap_vert");
    auto FragmentShader= CVulkanContext::Get()->GetShaderManager()->GetVulkanOnlyShader(U"PointLightShadowMap_frag");

    vk::PipelineShaderStageCreateInfo PipelineShaderStageCreateInfo[2]={
        vk::PipelineShaderStageCreateInfo()
            .setStage(vk::ShaderStageFlagBits::eVertex)
            .setModule(VertexShader->Module)
            .setPName("main"),
        vk::PipelineShaderStageCreateInfo()
            .setStage(vk::ShaderStageFlagBits::eFragment)
            .setModule(FragmentShader->Module)
            .setPName("main")
    };

    //only use mesh position
    vk::VertexInputAttributeDescription VertexInputAttributeDescription=vk::VertexInputAttributeDescription()
        .setBinding(0)
        .setLocation(0)
        .setFormat(vk::Format::eR32G32B32Sfloat)
        .setOffset(offsetof(SVertex,Position));

    auto VertexInputBindingDescriptions=CVulkanContext::Get()->GetMeshVertexInputBindingDescriptions();

    vk::PipelineVertexInputStateCreateInfo PipelineVertexInputStateCreateInfo=vk::PipelineVertexInputStateCreateInfo()
        .setVertexBindingDescriptionCount(1)
        .setPVertexBindingDescriptions(VertexInputBindingDescriptions.Data())
        .setVertexAttributeDescriptionCount(1)
        .setPVertexAttributeDescriptions(&VertexInputAttributeDescription);


    vk::PipelineInputAssemblyStateCreateInfo PipelineInputAssemblyStateCreateInfo=vk::PipelineInputAssemblyStateCreateInfo()
        .setTopology(vk::PrimitiveTopology::eTriangleList)
        .setPrimitiveRestartEnable(false);

    SpotLightShadowMapExtent=vk::Extent2D(2048,2048);

    vk::Viewport Viewport=vk::Viewport()
        .setX(0)
        .setY(0)
        .setWidth(SpotLightShadowMapExtent.width)
        .setHeight(SpotLightShadowMapExtent.height)
        .setMinDepth(0)
        .setMaxDepth(1);

    vk::Rect2D Scissor=vk::Rect2D()
        .setOffset(vk::Offset2D(0,0))
        .setExtent(SpotLightShadowMapExtent);

    vk::PipelineViewportStateCreateInfo PipelineViewportStateCreateInfo=vk::PipelineViewportStateCreateInfo()
        .setViewportCount(1)
        .setPViewports(&Viewport)
        .setScissorCount(1)
        .setPScissors(&Scissor);
        ;

    vk::PipelineRasterizationStateCreateInfo PipelineRasterizationStateCreateInfo=vk::PipelineRasterizationStateCreateInfo()
        .setDepthClampEnable(false)
        .setRasterizerDiscardEnable(false)
        .setPolygonMode(vk::PolygonMode::eFill)
        .setCullMode(vk::CullModeFlagBits::eBack)
        .setFrontFace(vk::FrontFace::eCounterClockwise)
        .setDepthBiasEnable(false)
        .setDepthBiasConstantFactor(0)
        .setDepthBiasClamp(0)
        .setDepthBiasSlopeFactor(0)
        .setLineWidth(1);

    vk::PipelineMultisampleStateCreateInfo PipelineMultisampleStateCreateInfo=vk::PipelineMultisampleStateCreateInfo()
        .setRasterizationSamples(vk::SampleCountFlagBits::e1)
        .setSampleShadingEnable(false)
        .setMinSampleShading(0)
        .setPSampleMask(nullptr)
        .setAlphaToCoverageEnable(false)
        .setAlphaToOneEnable(false);

    vk::PipelineDepthStencilStateCreateInfo PipelineDepthStencilStateCreateInfo=vk::PipelineDepthStencilStateCreateInfo()
        .setDepthTestEnable(true)
        .setDepthWriteEnable(true)
        .setDepthCompareOp(vk::CompareOp::eLess)
        .setDepthBoundsTestEnable(false)
        .setStencilTestEnable(false);

    vk::PipelineColorBlendAttachmentState PipelineColorBlendAttachmentState=vk::PipelineColorBlendAttachmentState()
        .setColorWriteMask(
            vk::ColorComponentFlagBits::eR
            |vk::ColorComponentFlagBits::eG
            |vk::ColorComponentFlagBits::eB
            |vk::ColorComponentFlagBits::eA
        )
        .setBlendEnable(false)
        .setSrcColorBlendFactor(vk::BlendFactor::eOne)
        .setDstColorBlendFactor(vk::BlendFactor::eOne)
        .setColorBlendOp(vk::BlendOp::eAdd)     //just add color with both weight is 1
        .setSrcAlphaBlendFactor(vk::BlendFactor::eOne)
        .setDstAlphaBlendFactor(vk::BlendFactor::eZero)
        .setAlphaBlendOp(vk::BlendOp::eAdd);

    vk::PipelineColorBlendStateCreateInfo PipelineColorBlendStateCreateInfo=vk::PipelineColorBlendStateCreateInfo()
        .setAttachmentCount(1)
        .setPAttachments(&PipelineColorBlendAttachmentState);

    vk::GraphicsPipelineCreateInfo GraphicsPipelineCreateInfo=vk::GraphicsPipelineCreateInfo()
        .setStages(PipelineShaderStageCreateInfo)
        .setPVertexInputState(&PipelineVertexInputStateCreateInfo)
        .setPInputAssemblyState(&PipelineInputAssemblyStateCreateInfo)
        .setPViewportState(&PipelineViewportStateCreateInfo)
        .setPRasterizationState(&PipelineRasterizationStateCreateInfo)
        .setPMultisampleState(&PipelineMultisampleStateCreateInfo)
        .setPDepthStencilState(&PipelineDepthStencilStateCreateInfo)
        .setPColorBlendState(&PipelineColorBlendStateCreateInfo)
        .setPDynamicState(nullptr)
        .setLayout(SpotLightShadowMapPipelineLayout)
        .setRenderPass(SpotLightShadowMapRenderPass)
        .setSubpass(0);

    SpotLightShadowMapPipeline=CVulkanContext::Get()->GetDevice().createGraphicsPipeline(nullptr,GraphicsPipelineCreateInfo).value;
    
}

void CSceneGlobal::CreateDirectionalLightShadowMapThings()
{
    //same with spot light
    vk::AttachmentDescription AttachmentDescription=vk::AttachmentDescription()
        .setFormat(DirectionalLightShadowMapImageFormat)
        .setSamples(vk::SampleCountFlagBits::e1)
        .setLoadOp(vk::AttachmentLoadOp::eClear)
        .setStoreOp(vk::AttachmentStoreOp::eStore)
        .setStencilLoadOp(vk::AttachmentLoadOp::eDontCare)
        .setStencilStoreOp(vk::AttachmentStoreOp::eDontCare)
        .setInitialLayout(vk::ImageLayout::eUndefined)
        .setFinalLayout(vk::ImageLayout::eDepthStencilReadOnlyOptimal);

    vk::AttachmentReference AttachmentReference=vk::AttachmentReference()
        .setAttachment(0)
        .setLayout(vk::ImageLayout::eDepthStencilAttachmentOptimal);

    vk::SubpassDescription SubpassDescription=vk::SubpassDescription()
        .setPipelineBindPoint(vk::PipelineBindPoint::eGraphics)
        .setInputAttachmentCount(0)
        .setPInputAttachments(nullptr)
        .setColorAttachmentCount(0)
        .setPColorAttachments(nullptr)
        .setPResolveAttachments(nullptr)
        .setPDepthStencilAttachment(&AttachmentReference)
        .setPreserveAttachmentCount(0)
        .setPPreserveAttachments(nullptr);

    vk::RenderPassCreateInfo RenderPassCreateInfo=vk::RenderPassCreateInfo()
        .setAttachmentCount(1)
        .setPAttachments(&AttachmentDescription)
        .setSubpassCount(1)
        .setPSubpasses(&SubpassDescription);

    DirectionalLightShadowMapRenderPass=CVulkanContext::Get()->GetDevice().createRenderPass(RenderPassCreateInfo);
    

    //create pipeline layout
    vk::PushConstantRange PushConstantRange=vk::PushConstantRange()
        .setStageFlags(vk::ShaderStageFlagBits::eVertex)
        .setOffset(0)
        .setSize(sizeof(SDirectionalLightVertexPushConstant));

    TVector<vk::DescriptorSetLayout> DescriptorSetLayouts=
    {
        ModelDescriptorSetLayout.Layout
    };

    vk::PipelineLayoutCreateInfo PipelineLayoutCreateInfo=vk::PipelineLayoutCreateInfo()
        .setSetLayouts(DescriptorSetLayouts)
        .setPushConstantRangeCount(1)
        .setPPushConstantRanges(&PushConstantRange);

    DirectionalLightShadowMapPipelineLayout=CVulkanContext::Get()->GetDevice().createPipelineLayout(PipelineLayoutCreateInfo);

    //create pipeline
    auto VertexShader= CVulkanContext::Get()->GetShaderManager()->GetVulkanOnlyShader(U"DirectionalLightShadowMap_vert");

    vk::PipelineShaderStageCreateInfo PipelineShaderStageCreateInfo[1]={
        vk::PipelineShaderStageCreateInfo()
            .setStage(vk::ShaderStageFlagBits::eVertex)
            .setModule(VertexShader->Module)
            .setPName("main"),
    };

    //only use mesh position
    vk::VertexInputAttributeDescription VertexInputAttributeDescription=vk::VertexInputAttributeDescription()
        .setBinding(0)
        .setLocation(0)
        .setFormat(vk::Format::eR32G32B32Sfloat)
        .setOffset(offsetof(SVertex,Position));

    auto VertexInputBindingDescriptions=CVulkanContext::Get()->GetMeshVertexInputBindingDescriptions();

    vk::PipelineVertexInputStateCreateInfo PipelineVertexInputStateCreateInfo=vk::PipelineVertexInputStateCreateInfo()
        .setVertexBindingDescriptionCount(1)
        .setPVertexBindingDescriptions(VertexInputBindingDescriptions.Data())
        .setVertexAttributeDescriptionCount(1)
        .setPVertexAttributeDescriptions(&VertexInputAttributeDescription);

    
    vk::PipelineInputAssemblyStateCreateInfo PipelineInputAssemblyStateCreateInfo=vk::PipelineInputAssemblyStateCreateInfo()
        .setTopology(vk::PrimitiveTopology::eTriangleList)
        .setPrimitiveRestartEnable(false);

    vk::Viewport Viewport=vk::Viewport()
        .setX(0)
        .setY(0)
        .setWidth(DirectionalLightShadowMapExtent.width)
        .setHeight(DirectionalLightShadowMapExtent.height)
        .setMinDepth(0)
        .setMaxDepth(1);

    vk::Rect2D Scissor=vk::Rect2D()
        .setOffset(vk::Offset2D(0,0))
        .setExtent(DirectionalLightShadowMapExtent);

    vk::PipelineViewportStateCreateInfo PipelineViewportStateCreateInfo=vk::PipelineViewportStateCreateInfo()
        .setViewportCount(1)
        .setPViewports(&Viewport)
        .setScissorCount(1)
        .setPScissors(&Scissor);
        ;

    vk::PipelineRasterizationStateCreateInfo PipelineRasterizationStateCreateInfo=vk::PipelineRasterizationStateCreateInfo()
        .setDepthClampEnable(false)
        .setRasterizerDiscardEnable(false)
        .setPolygonMode(vk::PolygonMode::eFill)
        .setCullMode(vk::CullModeFlagBits::eBack)
        .setFrontFace(vk::FrontFace::eCounterClockwise)
        .setDepthBiasEnable(false)
        .setDepthBiasConstantFactor(0)
        .setDepthBiasClamp(0)
        .setDepthBiasSlopeFactor(0)
        .setLineWidth(1);

    vk::PipelineMultisampleStateCreateInfo PipelineMultisampleStateCreateInfo=vk::PipelineMultisampleStateCreateInfo()
        .setRasterizationSamples(vk::SampleCountFlagBits::e1)
        .setSampleShadingEnable(false)
        .setMinSampleShading(0)
        .setPSampleMask(nullptr)
        .setAlphaToCoverageEnable(false)
        .setAlphaToOneEnable(false);

    vk::PipelineDepthStencilStateCreateInfo PipelineDepthStencilStateCreateInfo=vk::PipelineDepthStencilStateCreateInfo()
        .setDepthTestEnable(true)
        .setDepthWriteEnable(true)
        .setDepthCompareOp(vk::CompareOp::eLess)
        .setDepthBoundsTestEnable(false)
        .setStencilTestEnable(false);

    vk::PipelineColorBlendStateCreateInfo PipelineColorBlendStateCreateInfo=vk::PipelineColorBlendStateCreateInfo()
        .setAttachmentCount(0)
        .setPAttachments(nullptr);

    vk::GraphicsPipelineCreateInfo GraphicsPipelineCreateInfo=vk::GraphicsPipelineCreateInfo()
        .setRenderPass(DirectionalLightShadowMapRenderPass)
        .setSubpass(0)
        .setBasePipelineHandle(nullptr)
        .setBasePipelineIndex(-1)
        .setStageCount(1)
        .setPStages(PipelineShaderStageCreateInfo)
        .setPVertexInputState(&PipelineVertexInputStateCreateInfo)
        .setPInputAssemblyState(&PipelineInputAssemblyStateCreateInfo)
        .setPViewportState(&PipelineViewportStateCreateInfo)
        .setPRasterizationState(&PipelineRasterizationStateCreateInfo)
        .setPMultisampleState(&PipelineMultisampleStateCreateInfo)
        .setPDepthStencilState(&PipelineDepthStencilStateCreateInfo)
        .setPColorBlendState(&PipelineColorBlendStateCreateInfo)
        .setPDynamicState(nullptr)
        .setLayout(DirectionalLightShadowMapPipelineLayout);

    DirectionalLightShadowMapPipeline=CVulkanContext::Get()->GetDevice().createGraphicsPipeline(nullptr,GraphicsPipelineCreateInfo).value;    
}

void CSceneGlobal::CreateAntiAliasingPipeline()
{

    //抗锯齿仅需要一个输入图像
    TVector<vk::DescriptorSetLayoutBinding> DescriptorSetLayoutBindings=
    {
        //延迟渲染的输出
        vk::DescriptorSetLayoutBinding()
            .setBinding(0)
            .setDescriptorType(vk::DescriptorType::eCombinedImageSampler)
            .setDescriptorCount(1)
            .setStageFlags(vk::ShaderStageFlagBits::eFragment)
            .setPImmutableSamplers(nullptr)
        ,
    };

    {
        vk::DescriptorSetLayoutCreateInfo DescriptorSetLayoutCreateInfo = vk::DescriptorSetLayoutCreateInfo()
            .setBindings(DescriptorSetLayoutBindings);

        AntiAliasingDescriptorSetLayout.Layout =CVulkanContext::Get()->GetDevice().createDescriptorSetLayout(DescriptorSetLayoutCreateInfo);
        AntiAliasingDescriptorSetLayout.DescriptorNums.CombinedImageSamplerDescriptorNum=1;
    }

    //创建管线布局
    {
        TVector<vk::DescriptorSetLayout> DescriptorSetLayouts=
        {
            AntiAliasingDescriptorSetLayout.Layout
        };

        vk::PipelineLayoutCreateInfo PipelineLayoutCreateInfo = vk::PipelineLayoutCreateInfo()
            .setSetLayouts(DescriptorSetLayouts);

        AntiAliasingPipelineLayout =CVulkanContext::Get()->GetDevice().createPipelineLayout(PipelineLayoutCreateInfo);
    }

    //创建渲染通道
    {
        vk::AttachmentDescription AttachmentDescriptions=
        {
            vk::AttachmentDescription()
                .setFormat(vk::Format::eR16G16B16A16Sfloat)
                .setSamples(vk::SampleCountFlagBits::e1)
                .setLoadOp(vk::AttachmentLoadOp::eDontCare)
                .setStoreOp(vk::AttachmentStoreOp::eStore)
                .setStencilLoadOp(vk::AttachmentLoadOp::eDontCare)
                .setStencilStoreOp(vk::AttachmentStoreOp::eDontCare)
                .setInitialLayout(vk::ImageLayout::eUndefined)
                .setFinalLayout(vk::ImageLayout::eShaderReadOnlyOptimal)
        };

        vk::AttachmentReference AttachmentReference=
            vk::AttachmentReference()
            .setAttachment(0)
            .setLayout(vk::ImageLayout::eColorAttachmentOptimal);

        vk::SubpassDescription SubpassDescription=
        {
            vk::SubpassDescription()
                .setPipelineBindPoint(vk::PipelineBindPoint::eGraphics)
                .setColorAttachmentCount(1)
                .setPColorAttachments(&AttachmentReference)
        };

        vk::SubpassDependency SubpassDependency=
        {
            vk::SubpassDependency()
                .setSrcSubpass(VK_SUBPASS_EXTERNAL)
                .setDstSubpass(0)
                .setSrcStageMask(vk::PipelineStageFlagBits::eColorAttachmentOutput)
                .setDstStageMask(vk::PipelineStageFlagBits::eColorAttachmentOutput)
                .setSrcAccessMask(vk::AccessFlagBits::eColorAttachmentWrite)
                .setDstAccessMask(vk::AccessFlagBits::eColorAttachmentWrite)
                .setDependencyFlags(vk::DependencyFlagBits::eByRegion)
        };

        vk::RenderPassCreateInfo RenderPassCreateInfo=vk::RenderPassCreateInfo()
            .setAttachments(AttachmentDescriptions)
            .setSubpasses(SubpassDescription)
            .setDependencies(SubpassDependency)
            ;

        AntiAliasingRenderPass=CVulkanContext::Get()->GetDevice().createRenderPass(RenderPassCreateInfo);
    }

    //创建管线
    {
        auto VertexShader= CVulkanContext::Get()->GetShaderManager()->GetVulkanOnlyShader(U"FXAA_vert");
        auto FragmentShader= CVulkanContext::Get()->GetShaderManager()->GetVulkanOnlyShader(U"FXAA_frag");

        //dynamic state
        vk::DynamicState DynamicState[2]={vk::DynamicState::eViewport,vk::DynamicState::eScissor};

        vk::PipelineDynamicStateCreateInfo PipelineDynamicStateCreateInfo=vk::PipelineDynamicStateCreateInfo()
            .setDynamicStateCount(2)
            .setPDynamicStates(DynamicState);

        vk::PipelineShaderStageCreateInfo PipelineShaderStageCreateInfo[2];
        PipelineShaderStageCreateInfo[0]=vk::PipelineShaderStageCreateInfo()
            .setStage(vk::ShaderStageFlagBits::eVertex)
            .setModule(VertexShader->Module)
            .setPName("main");

        PipelineShaderStageCreateInfo[1]=vk::PipelineShaderStageCreateInfo()
            .setStage(vk::ShaderStageFlagBits::eFragment)
            .setModule(FragmentShader->Module)
            .setPName("main");

        vk::PipelineVertexInputStateCreateInfo PipelineVertexInputStateCreateInfo=vk::PipelineVertexInputStateCreateInfo()
            .setVertexBindingDescriptionCount(0)
            .setVertexAttributeDescriptionCount(0);

        vk::PipelineInputAssemblyStateCreateInfo PipelineInputAssemblyStateCreateInfo=vk::PipelineInputAssemblyStateCreateInfo()
            .setTopology(vk::PrimitiveTopology::eTriangleStrip);

        vk::PipelineViewportStateCreateInfo PipelineViewportStateCreateInfo=vk::PipelineViewportStateCreateInfo()
            .setViewportCount(1)
            .setScissorCount(1);

        vk::PipelineRasterizationStateCreateInfo PipelineRasterizationStateCreateInfo=vk::PipelineRasterizationStateCreateInfo()
            .setPolygonMode(vk::PolygonMode::eFill)
            .setCullMode(vk::CullModeFlagBits::eNone)
            .setFrontFace(vk::FrontFace::eClockwise)
            .setLineWidth(1.0f);

        vk::PipelineMultisampleStateCreateInfo PipelineMultisampleStateCreateInfo=
            vk::PipelineMultisampleStateCreateInfo()
            .setRasterizationSamples(vk::SampleCountFlagBits::e1);

        vk::PipelineDepthStencilStateCreateInfo PipelineDepthStencilStateCreateInfo=vk::PipelineDepthStencilStateCreateInfo()
            .setDepthTestEnable(false)
            .setDepthWriteEnable(false)
            .setDepthCompareOp(vk::CompareOp::eLessOrEqual)
            .setDepthBoundsTestEnable(false)
            .setStencilTestEnable(false);

        vk::PipelineColorBlendAttachmentState PipelineColorBlendAttachmentState=vk::PipelineColorBlendAttachmentState()
                .setColorWriteMask(
                    vk::ColorComponentFlagBits::eR
                    |vk::ColorComponentFlagBits::eG
                    |vk::ColorComponentFlagBits::eB
                    |vk::ColorComponentFlagBits::eA
                )
                .setBlendEnable(false)
                .setSrcColorBlendFactor(vk::BlendFactor::eOne)
                .setDstColorBlendFactor(vk::BlendFactor::eOne)
                .setColorBlendOp(vk::BlendOp::eAdd)     //just add color with both weight is 1
                .setSrcAlphaBlendFactor(vk::BlendFactor::eOne)
                .setDstAlphaBlendFactor(vk::BlendFactor::eZero)
                .setAlphaBlendOp(vk::BlendOp::eAdd);

        vk::PipelineColorBlendStateCreateInfo PipelineColorBlendStateCreateInfo=vk::PipelineColorBlendStateCreateInfo()
            .setAttachmentCount(1)
            .setPAttachments(&PipelineColorBlendAttachmentState);

        vk::GraphicsPipelineCreateInfo GraphicsPipelineCreateInfo=vk::GraphicsPipelineCreateInfo()
            .setPDynamicState(&PipelineDynamicStateCreateInfo)
            .setStageCount(2)
            .setPStages(PipelineShaderStageCreateInfo)
            .setPVertexInputState(&PipelineVertexInputStateCreateInfo)
            .setPInputAssemblyState(&PipelineInputAssemblyStateCreateInfo)
            .setPViewportState(&PipelineViewportStateCreateInfo)
            .setPRasterizationState(&PipelineRasterizationStateCreateInfo)
            .setPMultisampleState(&PipelineMultisampleStateCreateInfo)
            .setPDepthStencilState(&PipelineDepthStencilStateCreateInfo)
            .setPColorBlendState(&PipelineColorBlendStateCreateInfo)
            .setLayout(AntiAliasingPipelineLayout)
            .setRenderPass(AntiAliasingRenderPass)
            .setSubpass(0);

        AntiAliasingPipeline=CVulkanContext::Get()->GetDevice().createGraphicsPipeline(nullptr,GraphicsPipelineCreateInfo).value;

    }
}
